﻿/* 
Copyright (c) 2009, Aaron Moline <Aaron.Moline@MolineSoftware.com>

Permission is hereby granted, free of charge, to any person 
obtaining a copy of this software and associated documentation 
files (the "Software"), to deal in the Software without restriction, 
including without limitation the rights to use, copy, modify, merge, 
publish, distribute, sublicense, and/or sell copies of the Software, 
and to permit persons to whom the Software is furnished to do so, 
subject to the following conditions:

The above copyright notice and this permission notice shall be 
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE SOFTWARE.
*/

using System;
using System.Collections.Generic;
using CookComputing.XmlRpc;


namespace MolineSoftware.DrupalXmlRpc
{
    //TODO: Change all Set values classs to XmlRpcSturct and user the Convert<> where available.

    /// <summary>
    /// Interface: Should be used with <see cref="IXmlRpcProxy"/>
    /// </summary>
    public interface IDrupalXmlRpc : IXmlRpcProxy , IDisposable //TODO: Impliment disposable.
    {
        #region | Connection Methods |
        /// <summary>
        /// Connect to the Drupal XmlRpc Service Asynchronously.
        /// </summary>
        /// <param name="acb">The <see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("system.connect")]
        IAsyncResult BeginConnect(AsyncCallback acb);

        /// <summary>
        /// Retrieves the return value of the asynchronous operation represented by the System.IAsyncResult passed.
        /// </summary>
        /// <param name="asr"><see cref="IAsyncResult"/></param>
        /// <returns><see cref="Drupal"/></returns>
        [XmlRpcEnd]
        Drupal EndConnect(IAsyncResult asr);

        /// <summary>
        /// Connect to the Drupal XmlRpc Service
        /// </summary>
        /// <returns><see cref="Drupal"/></returns>
        [XmlRpcMethod("system.connect")]
        Drupal Connect();
        #endregion

        #region | Login/Logout Methods |

        /// <summary>
        /// Login to the Drupal XmlRpc Service Asynchronously.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="username">The username to log into Drupal.</param>
        /// <param name="password">The password to log into Drupal.</param>
        /// <param name="acb"><see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("user.login")]
        IAsyncResult BeginLogin(string hash, string domain, string timestamp,
            string nonce, string sessionId, string username, string password, AsyncCallback acb);//, object drupal);

        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="asr">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="Drupal"/></returns>
        [XmlRpcEnd]
        Drupal EndLogin(IAsyncResult asr);

        /// <summary>
        /// Login to a new instance of Drupal XmlRpc
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="username">The username to log into Drupal.</param>
        /// <param name="password">The password to log into Drupal.</param>
        /// <returns></returns>
        [XmlRpcMethod("user.login")]
        Drupal Login(string hash, string domain, string timestamp, string nonce,
            string sessionId, string username, string password);

        /// <summary>
        /// Logout of the current Session.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <returns><see cref="bool"/></returns>
        [XmlRpcMethod("user.logout")]
        bool Logout(string hash, string domain, string timestamp, string nonce, string sessionId);

        /// <summary>
        /// Begins Logout of the current Session.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="acb">The <see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("user.logout")]
        IAsyncResult BeginLogout(string hash, string domain, string timestamp, string nonce, string sessionId, AsyncCallback acb);


        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="asr">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="bool"/></returns>
        [XmlRpcEnd("user.logout")]
        bool EndLogout(IAsyncResult asr);
        #endregion

        #region | Node Methods |
        /// <summary>
        /// Returns a <see cref="DrupalNode"/>.
        /// </summary>
        /// <param name="sessid">A valid sessid.</param>
        /// <param name="nid">A node ID.</param>
        /// <param name="fields">A list of fields to return.</param>
        /// <returns><see cref="DrupalNode"/></returns>
        [XmlRpcMethod("node.get")]
        XmlRpcStruct NodeGet(string hash, string domain, string timestamp, string nonce, 
            string sessid, int nid, string[] fields);
        
        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="sessid">A valid sessid.</param>
        /// <param name="nid">A node ID.</param>
        /// <param name="fields">A list of fields to return.</param>
        /// <param name="acb">The <see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("node.get")]
        IAsyncResult BeginNodeGet(string hash, string domain, string timestamp, string nonce, 
            string sessid, int nid, string[] fields, AsyncCallback acb);

        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="asr">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="DrupalNode"/></returns>
        [XmlRpcEnd]
        XmlRpcStruct EndNodeGet(IAsyncResult asr);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="node">A <see cref="XmlRpcStruct"/> object. Upon creation, node object must include "type". 
        /// Upon update, node object must include "nid" and "changed".</param>
        /// <returns></returns>
        [XmlRpcMethod("node.save")]
        string NodeSave(string hash, string domain, string timestamp, string nonce, string sessionId, XmlRpcStruct node);

        /// <summary>
        /// Saves a new node asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="node">A <see cref="XmlRpcStruct"/> object. Upon creation, node object must include "type". 
        /// Upon update, node object must include "nid" and "changed".</param>
        /// <param name="acb"><see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("node.save")]
        IAsyncResult BeginNodeSave(string hash, string domain, string timestamp, string nonce,
            string sessionId, XmlRpcStruct node, AsyncCallback acb);


        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="asr"></param>
        /// <returns></returns>
        [XmlRpcEnd("node.save")]
        string EndNodeSave(IAsyncResult asr);


        /// <summary>
        /// Delete's node asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="nid">The nid of the node to delete</param>
        /// <param name="acb"><see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("node.delete")]
        IAsyncResult BeginNodeDelete(string hash, string domain, string timestamp, string nonce,
            string sessionId, int nid, AsyncCallback acb);

        /// <summary>
        /// Deletes specifed node.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="nid">The nodeID to delete</param>
        [XmlRpcMethod("node.delete")]
        string NodeDelete(string hash, string domain, string timestamp, string nonce,
            string sessionId, int nid);


        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="asr"></param>
        /// <returns></returns>
        [XmlRpcEnd("node.delete")]
        string EndNodeDelete(IAsyncResult asr);
        #endregion

        #region | Mail Methods |
        /// <summary>
        /// Send an e-mail message, using Drupal variables and default settings.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="doman">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="mailkey">A key to identify the mail sent, for altering.</param>
        /// <param name="receipent">The mail address or addresses where the message will be send to.</param>
        /// <param name="subject">Subject of the e-mail to be sent. This must not contain any newline characters, or the mail may not be sent properly.</param>
        /// <param name="body">Message to be sent. Drupal will format the correct line endings for you.</param>
        /// <param name="from">Sets From, Reply-To, Return-Path and Error-To to this value, if given.</param>
        /// <param name="headers">Associative array containing the headers to add. This is typically used to add extra headers (From, Cc, and Bcc).</param>
        [XmlRpcMethod("system.mail")]
        DrupalMail MailSend(string hash, string doman, string timestamp, string nonce, string sessionId, string mailkey,
            string receipent, string subject, string body, string from, DrupalMailHeader headers);

        /// <summary>
        /// Send an e-mail message, using Drupal variables and default settings.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="doman">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionId">A valid sessid.</param>
        /// <param name="mailkey">A key to identify the mail sent, for altering.</param>
        /// <param name="receipent">The mail address or addresses where the message will be send to.</param>
        /// <param name="subject">Subject of the e-mail to be sent. This must not contain any newline characters, or the mail may not be sent properly.</param>
        /// <param name="body">Message to be sent. Drupal will format the correct line endings for you.</param>
        /// <param name="from">Sets From, Reply-To, Return-Path and Error-To to this value, if given.</param>
        /// <param name="headers">Associative array containing the headers to add. This is typically used to add extra headers (From, Cc, and Bcc).</param>
        /// <param name="acb">The <see cref="AsyncCallback"/></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("system.mail")]
        IAsyncResult BeginMailSend(string hash, string doman, string timestamp, string nonce, string sessionId, string mailkey,
            string receipent, string subject, string body, string from, DrupalMailHeader headers, AsyncCallback acb);

        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.        
        /// </summary>
        /// <param name="asr">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="DrupalMail"/></returns>
        [XmlRpcEnd("system.mail")]
        DrupalMail EndMailSend(IAsyncResult asr);
        #endregion

        #region | User Methods |
        /// <summary>
        /// Get all user details.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionID">A valid sessid.</param>
        /// <param name="userID">User ID.</param>
        /// <returns><see cref="DrupalUser"/></returns>
        [XmlRpcMethod("user.get")]
        XmlRpcStruct UserGet(string hash, string domain, string timestamp, string nonce, string sessionID, int userID);

        /// <summary>
        /// Get all user details.
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionID">A valid sessid.</param>
        /// <param name="userID">User ID.</param>
        /// <returns><see cref="DrupalUser"/></returns>
        [XmlRpcBegin("user.get")]
        IAsyncResult BeginUserGet(string hash, string domain, string timestamp,
            string nonce, string sessionID, int userID, AsyncCallback acb);


        [XmlRpcEnd("user.get")]
        XmlRpcStruct EndUserGet(IAsyncResult asr);

        /// <summary>
        /// Searches users according to keys via hook_search.
        /// </summary>
        /// <param name="sessionID">A valid sessid.</param>
        /// <param name="user">Search keys.</param>
        /// <returns><see cref="XmlRpcStruct"/></returns>
        [XmlRpcMethod("search.users")]
        XmlRpcStruct UserSearch(string sessionID, string user);
        #endregion

        #region | File Methods |
        /// <summary>
        /// Gets a file from Drupal
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionID">A valid sessid.</param>
        /// <param name="fid">The file ID.</param>
        /// <returns><see cref="DrupalFileNode"/></returns>
        [XmlRpcMethod("file.get")]
        DrupalFileNode FileGet(string hash, string domain, string timestamp, string nonce,
            string sessionID, int fid);

        /// <summary>
        /// Gets a file from Drupal
        /// </summary>
        /// <param name="hash">A valid API key.</param>
        /// <param name="domain">A valid domain for the API key.</param>
        /// <param name="timestamp">Time stamp used to hash key.</param>
        /// <param name="nonce">One time use nonce also used hash key.</param>
        /// <param name="sessionID">A valid sessid.</param>
        /// <param name="fid">The file ID.</param>
        /// <param name="acb"></param>
        /// <returns></returns>
        [XmlRpcBegin("file.get")]
        IAsyncResult BeginFileGet(string hash, string domain, string timestamp, string nonce,
            string sessionID, int fid, AsyncCallback acb);

        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.  
        /// </summary>
        /// <param name="result">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="DrupalFileNode"/></returns>
        [XmlRpcEnd("file.get")]
        DrupalFileNode EndFileGet(IAsyncResult result);
        #endregion

        #region | Service Searches |
        /// <summary>
        /// Search Nodes
        /// </summary>
        /// <param name="sessid">A valid sessid.</param>
        /// <param name="search_keys">Seach keys "Title,body...etc"</param>
        /// <param name="simple">The string to search for</param>
        /// <returns>Array of <see cref="DrupalNodeSearchResult"/></returns>
        [XmlRpcMethod("search.nodes")]
        XmlRpcStruct[] SearchNodes(string hash, string domain, string timestamp, string nonce, string sessionId,
            string search_keys, string simple, string[] fields);

        /// <summary>
        /// Searchs drupal content nodes.
        /// </summary>
        /// <param name="sessid">A valid sessid</param>
        /// <param name="search_keys">Seach keys "Title,body...etc"</param>
        /// <param name="simple">The string to search for</param>
        /// <param name="acb"></param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("search.nodes")]
        IAsyncResult BeginSearchNodes(string hash, string domain, string timestamp, string nonce, string sessionId,
            string search_keys, string simple, string[] fields, AsyncCallback acb);

        /// <summary>
        /// Retrieves the return value of the asynchronous operation 
        /// represented by the <see cref="System.IAsyncResult"/> passed.
        /// </summary>
        /// <param name="asr">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="DrupalNode"/></returns>
        [XmlRpcEnd]
        XmlRpcStruct[] EndSearchNodes(IAsyncResult asr);


        /// <summary>
        /// Search Drupal host for user account.
        /// </summary>
        /// <param name="session_id">The sessionID</param>
        /// <param name="search_keys">The name to search for.</param>
        /// <returns><see cref="DrupalUser"/></returns>
        [XmlRpcMethod("search.users")]
        DrupalUser SearchUsers(string session_id, string search_keys);

        /// <summary>
        /// Searches users Asynchronously.
        /// </summary>
        /// <param name="session_id">The sessionID</param>
        /// <param name="search_keys">The name to search for.</param>
        /// <returns><see cref="IAsyncResult"/></returns>
        [XmlRpcBegin("search.users")]
        IAsyncResult BeginSearchUsers(string session_id, string search_keys);

        /// <summary>
        /// End Search Call.
        /// </summary>
        /// <param name="asr">The <see cref="IAsyncResult"/></param>
        /// <returns><see cref="DrupalUser"/></returns>
        [XmlRpcEnd("search.users")]
        DrupalUser EndSearchUsers(IAsyncResult asr);
        #endregion

        #region | View Methods |

        [XmlRpcMethod("views.get")]
        XmlRpcStruct[] ViewsGet(string hash, string domain, string timestamp, string nonce,
            string sessionID, string view_name, string[] fields, string[] args, int offset, int limit);

        [XmlRpcBegin("views.get")]
        IAsyncResult BeginViewsGet(string hash, string domain, string timestamp, string nonce,
            string sessionID, string view_name, string[] fields, string[] args, int offset, int limit, AsyncCallback acb);


        [XmlRpcEnd("views.get")]
        XmlRpcStruct[] EndViewsGet(IAsyncResult result);
        #endregion
    }
}
